Notifications
One hook. One config.
The Config
Enable notifications with a single flag
config.json:
{
"WEBVIEW_CONFIG": {
"notifications": {
"enabled": true
}
}
}
The Hook
const { scheduleLocal, registerForPush, subscribeToTopic } = useNotification()
// Schedule local notification
scheduleLocal({
title: "Hey!",
body: "You got a message",
badge: 5,
})
scheduleLocal({
title: "New Friend Request",
body: "Sarah wants to be your friend",
data: {
type: "friend_request",
fromUserId: 456,
requestId: "req_789",
},
actions: [
{ title: "Accept", action: "accept" },
{ title: "Decline", action: "decline" },
],
})
// Register for push notifications
registerForPush()
// Subscribe to topics after registering for push
subscribeToTopic("news")
scheduleLocal Keys
Required Keys:
title(string) - notification title (default: "Notification")body(string) - notification body text (default: "You have a new message")
Optional Keys:
channel(string) - channel ID:"default"|"urgent"(default: "default")badge(number) - badge count on app iconactions(array) - action buttons[{title, action}]largeImage(string) - large image URL for notification body and BIG_IMAGE stylestyle(string) -"BASIC"|"BIG_TEXT"|"BIG_IMAGE"|"ACTION_BUTTONS"(default: "BASIC")priority(number) - notification priority (default: 0)vibrate(boolean) - enable vibration (default: true)autoCancel(boolean) - auto dismiss on tap (default: true)data(object) - extra data for notification endpoint
Notification Channels & Sound System
How sounds work now: Sounds are automatically configured per channel (required for Android 8.0+). You cannot set sounds per individual notification.
Two predefined channels with automatic sound configuration:
default(default channel)- Uses
notification_sound_default.mp3if available inpublic/ - Fallback: System default notification sound
- Importance: DEFAULT
- Uses
urgent- Uses
notification_sound_urgent.mp3if available inpublic/ - Fallback: System alarm sound
- Importance: HIGH
- Uses
Sound assets are completely optional - the system automatically falls back to appropriate system sounds if custom assets are not provided.
Notification Types
- Local: Triggers locally
- Push: Triggered by firebase
Styles
BASIC- title + text (default)BIG_TEXT- wall of text that expandsBIG_IMAGE- shows pictureACTION_BUTTONS- buttons
Deep Links → /notification Endpoint
All notification clicks route to /notification
Notification tap:
<ip>/notification?data={"orderId":123,"status":"shipped"}
Action button tap:
<ip>/notification?action=track_order&data={"orderId":123,"status":"shipped"}
Your middleware handles everything:
app.get("/notification", (req, res) => {
const { action, data } = req.query
const payload = JSON.parse(data || "{}")
if (action === "track_order") {
res.redirect(`/tracking/${payload.orderId}`)
} else if (action === "view_details") {
res.redirect(`/order/${payload.orderId}`)
} else {
// Regular notification click
res.redirect(`/order/${payload.orderId}`)
}
})
Assets Logic
Images
Build-time processing (automatic - both platforms):
- Place in
public/notification-icon.png→ Android:ic_notification, iOS:NotificationIcon - Place in
public/notification-large.png→ Android:ic_notification_large, iOS:NotificationLargeIcon - Android: Auto-copied to
res/drawable/during build - iOS: Auto-copied to
Assets.xcassets/during build - Accepted formats:
- Android: png, jpg, jpeg, gif, bmp, svg, webp
- iOS: png, jpg, jpeg, webp
- Fallback chain for icon: notification-icon.png -> app icon
- Fallback chain for large icon: notification url -> notification-large.png -> app icon
Runtime images:
scheduleLocal({
largeImage: "https://example.com/avatar.png", // optional large image URL
style: "BIG_IMAGE",
})
If fetching the image fails, normal icon and text are shown without the BIG_IMAGE style While the image is being loaded
Sounds
Build-time processing (automatic - both platforms):
- Place in
public/notification-sound-default.mp3→ becomesnotification_sound_default - Place in
public/notification-sound-urgent.mp3→ becomesnotification_sound_urgent - Android: Auto-copied to
res/raw/during build - iOS: Auto-copied to app bundle during build
- Accepted formats:
- Android: mp3, wav, ogg
- iOS: mp3, wav, m4a, caf (caf recommended for iOS)
How to use sounds:
// Default notification sound (system notification sound or custom asset)
scheduleLocal({
title: "New message",
body: "You have a new message",
// No channel specified = uses "default" channel automatically
})
// Same as above but explicit
scheduleLocal({
title: "New message",
body: "You have a new message",
channel: "default", // Uses notification_sound_default.mp3 if available, else system default
})
// Urgent notification sound (system alarm sound or custom asset)
scheduleLocal({
title: "Emergency Alert",
body: "Urgent attention required!",
channel: "urgent", // Uses notification_sound_urgent.mp3 if available, else system alarm
})
Push Notification Payload Format
Push notifications use exactly the same format as scheduleLocal(). Simply stringify the same object you would pass to scheduleLocal():
Example: Convert scheduleLocal to push:
// This object works with scheduleLocal
const notificationObj = {
title: "Order Update",
body: "Your order is ready!",
style: "BIG_TEXT",
channel: "urgent",
badge: 2,
data: {
orderId: "12345",
userId: "user123",
deepLink: "/orders/12345",
},
actions: [
{ action: "view", title: "View Order" },
{ action: "dismiss", title: "Dismiss" },
],
}
// For push, just stringify it
const pushPayload = {
to: "DEVICE_FCM_TOKEN",
data: {
payload: JSON.stringify(notificationObj),
},
}
Firebase Console Setup (Required for Push Notifications)
Step 1: Create Firebase Project
- Go to Firebase Console
- Click "Add project" or "Create project"
- Enter project name (same as defined in
config.json) - Accept terms and click "Create project"
- Wait for project creation to complete
Step 2: Add Android App
- In Firebase console, click Android icon to add Android app
- Enter your app's package name (same as defined in
config.json) - Click "Register app"
- Click "Download google-services.json" to download config file
- Place
google-services.jsonin your project's root directory - Click "Next" and finish the setup
Step 3: Add iOS App
- In Firebase console, click iOS+ icon to add iOS app
- Enter your app's bundle ID (same as defined in
config.json) - Click "Register app"
- Click "Download GoogleService-Info.plist" to download config file
- Place
GoogleService-Info.plistin your project's root directory - Click "Next" and finish the setup
Step 4: Enable Cloud Messaging
- In Firebase console, go to Project Settings
- Click "Cloud Messaging" tab
- Verify Cloud Messaging API is enabled (should be enabled by default)
- For iOS: Upload your APNs authentication key or certificate
- Go to Apple Developer Portal
- Create APNs authentication key
- Download the .p8 key file
- Upload key ID and team ID in Firebase console
Platform-Specific Requirements
iOS Requirements:
- Physical device required (push notifications don't work in simulator)
- Apple Developer account for APNs setup
- APNs authentication key configured in Firebase console
Android Requirements:
- Google Play Services installed on device
- Android 4.4+ (API level 19+) recommended
Firebase Initialization & Features
- Auto-Initialization: Firebase automatically initializes if config files are present
- Token Management: Automatic FCM token refresh and recovery
- Topic Subscription: Subscribe to topics with
subscribeToTopic()returns boolean success - Fallback Behavior: Local notifications work without Firebase setup
- Timeout Handling: 30-second timeout for FCM token retrieval with retry logic